package edu.java.homework.hw09.exercises.nikolay.food.salad;


import edu.java.homework.hw09.exercises.nikolay.food.ingredient.type.EggType;
import edu.java.homework.hw09.exercises.nikolay.food.ingredient.type.MeatType;
import edu.java.homework.hw09.exercises.nikolay.food.ingredient.type.MilkType;
import edu.java.homework.hw09.exercises.nikolay.food.ingredient.type.SpiceType;
import edu.java.homework.hw09.exercises.nikolay.food.ingredient.type.VegetableType;
import edu.java.homework.hw09.exercises.nikolay.food.product.EggProduct;
import edu.java.homework.hw09.exercises.nikolay.food.product.MeatProduct;
import edu.java.homework.hw09.exercises.nikolay.food.product.MilkProduct;
import edu.java.homework.hw09.exercises.nikolay.food.product.Product;
import edu.java.homework.hw09.exercises.nikolay.food.product.SpiceProduct;
import edu.java.homework.hw09.exercises.nikolay.food.product.VegetableProduct;

public class ShepherdSaladFactory extends SaladFactory {

	// --- Class Variables -----------------------------------------------------

	private static ShepherdSaladFactory instance;

	// --- Constructors --------------------------------------------------------

	private ShepherdSaladFactory() {
	}

	// --- Methods (Singleton) -------------------------------------------------

	public static ShepherdSaladFactory instance() {
		if (instance == null) {
			instance = new ShepherdSaladFactory();
		}
		return instance;
	}

	// --- Methods (Salad - Template Method) -----------------------------------

	@Override
	protected Salad initSalad() {
		String prefix = "[init-salad]\t\t";
		System.out.println(prefix + "Initializing the products...");
		MeatProduct ham = new MeatProduct(MeatType.HAM, 50); // 50 g ham
		EggProduct egg = new EggProduct(EggType.BOILED_EGG, 1); // 1 egg
		VegetableProduct[] vegetables = getVegetables();
		MilkProduct[] milkProducts = getMilkProducts();
		SpiceProduct[] spices = getSpices();
		int price = calculatePrice(ham, egg, vegetables, milkProducts, spices);

		ShepherdSalad shepherdSalad = new ShepherdSalad(price);
		shepherdSalad.setHam(ham);
		shepherdSalad.setEgg(egg);
		shepherdSalad.setVegetables(vegetables);
		shepherdSalad.setMilkProducts(milkProducts);
		shepherdSalad.setSpices(spices);

		System.out.println(prefix + "Products initialized.");
		return shepherdSalad;
	}

	@Override
	protected void washProducts(Salad salad) {
		if (salad == null) {
			throw new IllegalArgumentException(
					"Invalid argument - salad: null.");
		}
		ShepherdSalad shepherdSalad = (ShepherdSalad) salad;
		String prefix = "[wash-products]\t\t";
		System.out.print(prefix + "Washing the products: ");
		VegetableProduct[] vegetables = shepherdSalad.getVegetables();
		for (VegetableProduct vegetable : vegetables) {
			System.out.print(vegetable + "; ");
		}
		System.out.println(prefix + "Washing finished.");
	}

	@Override
	protected void boilProducts(Salad salad) {
		// do nothing
	}

	@Override
	protected void cutProducts(Salad salad) {
		if (salad == null) {
			throw new IllegalArgumentException(
					"Invalid argument - salad: null.");
		}
		ShepherdSalad shepherdSalad = (ShepherdSalad) salad;
		String prefix = "[cut-products]\t\t";
		System.out.print(prefix + "Cutting products: ");

		// cutting...
		printSemicolonSeparatedList(shepherdSalad.getVegetables());
		printSemicolonSeparatedList(shepherdSalad.getMilkProducts());
		System.out.println(shepherdSalad.getHam() + COMMA);
		System.out.println(shepherdSalad.getEgg() + COMMA);

		System.out.println(prefix + "Cutting finished.");
	}

	@Override
	protected void grateProducts(Salad salad) {
		// do nothing
	}

	@Override
	protected void mixProducts(Salad salad) {
		if (salad == null) {
			throw new IllegalArgumentException(
					"Invalid argument - salad: null.");
		}
		ShepherdSalad shepherdSalad = (ShepherdSalad) salad;
		String prefix = "[mix-products]\t\t";
		System.out.print(prefix + "Mixing products: ");

		// mixing...
		printSemicolonSeparatedList(shepherdSalad.getVegetables());
		System.out.print(shepherdSalad.getHam() + COMMA);
		System.out.print(shepherdSalad.getEgg() + COMMA);
		printSemicolonSeparatedList(shepherdSalad.getMilkProducts());
		printSemicolonSeparatedList(shepherdSalad.getSpices());
		System.out.println();

		System.out.println(prefix + "Mixing finished.");
	}

	// --- Methods (Salad) -----------------------------------------------------

	/**
	 * 100 g tomatoes, 50 g cucumbers, 20 g onion, 50 g corns, 50 g baken red
	 * peppers, 50 g marinate mushrooms, 3 olives, 10 g parsley
	 */
	@Override
	protected VegetableProduct[] getVegetables() {
		// preparing the products
		VegetableProduct tomatoes = new VegetableProduct(VegetableType.TOMATO,
				100);
		VegetableProduct cucumbers = new VegetableProduct(
				VegetableType.CUCUMBER, 50);
		VegetableProduct onion = new VegetableProduct(VegetableType.ONION, 20);
		VegetableProduct corns = new VegetableProduct(VegetableType.CORNS, 50);
		VegetableProduct bakedPeppers = new VegetableProduct(
				VegetableType.BAKED_RED_PEPPER, 50);
		VegetableProduct mushrooms = new VegetableProduct(
				VegetableType.MARINADE_MUSHROOMS, 50);
		VegetableProduct olives = new VegetableProduct(VegetableType.OLIVE, 3);
		VegetableProduct parsley = new VegetableProduct(VegetableType.PARSLEY,
				10);

		// preparing the result
		VegetableProduct[] vegetables = new VegetableProduct[] { tomatoes,
				cucumbers, onion, corns, bakedPeppers, mushrooms, olives,
				parsley };

		return vegetables;
	}

	// --- Methods -------------------------------------------------------------
	/**
	 * 50 g yellow cheese, 50 g white cheese
	 */
	private MilkProduct[] getMilkProducts() {
		MilkProduct yellowCheese = new MilkProduct(MilkType.YELLOW_CHEESE, 50);
		MilkProduct whiteCheese = new MilkProduct(MilkType.WHITE_CHEESE, 50);

		MilkProduct[] milkProducts = new MilkProduct[] { yellowCheese,
				whiteCheese };

		return milkProducts;
	}

	/**
	 * 10 ml oil, 5 g salt, 20 ml vinegar
	 */
	@Override
	protected SpiceProduct[] getSpices() {
		SpiceProduct oil = new SpiceProduct(SpiceType.OLIVE_OIL, 10);
		SpiceProduct salt = new SpiceProduct(SpiceType.SALT, 5);
		SpiceProduct vinegar = new SpiceProduct(SpiceType.VINEGAR, 20);

		SpiceProduct[] spices = new SpiceProduct[] { oil, salt, vinegar };

		return spices;
	}

	private int calculatePrice(MeatProduct ham, EggProduct egg,
			Product[]... products) {
		int price = 0;
		price += ham.getPrice();
		price += egg.getPrice();
		for (Product[] productsArr : products) {
			for (Product product : productsArr) {
				price += product.getPrice();
			}
		}
		return price;
	}
}
